#include <iostream>
#include <thread>

#include "lock_free_ring_queue.h"  // 假设你的类定义在这个文件中

void SingleProducerSingleConsumerExample() {
  LockFreeRingQueue<int> queue(4);

  // 单生产者线程入队
  std::thread producer([&queue]() {
    for (int i = 0; i < 4; ++i) {
      if (queue.Enqueue(i)) {
        std::cout << "Producer enqueued: " << i << std::endl;
      } else {
        std::cout << "Queue is full, cannot enqueue: " << i << std::endl;
      }
    }
  });

  // 单消费者线程出队
  std::thread consumer([&queue]() {
    int value = 0;
    for (int i = 0; i < 4; ++i) {
      while (!queue.Dequeue(&value)) {
        std::this_thread::yield();  // 等待队列中有数据
      }
      std::cout << "Consumer dequeued: " << value << std::endl;
    }
  });

  producer.join();
  consumer.join();
}

void MultiProducerMultiConsumerExample() {
  LockFreeRingQueue<int> queue(8);

  auto producer = [&queue](int id) {
    for (int i = 0; i < 4; ++i) {
      int value = id * 10 + i;
      if (queue.Enqueue(value)) {
        std::cout << "Producer " << id << " enqueued: " << value << std::endl;
      } else {
        std::cout << "Queue is full, Producer " << id << " cannot enqueue: " << value << std::endl;
      }
    }
  };

  auto consumer = [&queue](int id) {
    int value = 0;
    for (int i = 0; i < 4; ++i) {
      while (!queue.Dequeue(&value)) {
        std::this_thread::yield();  // 等待队列中有数据
      }
      std::cout << "Consumer " << id << " dequeued: " << value << std::endl;
    }
  };

  std::thread producers[2];
  std::thread consumers[2];

  // 启动两个生产者线程
  for (int i = 0; i < 2; ++i) {
    producers[i] = std::thread(producer, i);
  }

  // 启动两个消费者线程
  for (int i = 0; i < 2; ++i) {
    consumers[i] = std::thread(consumer, i);
  }

  for (auto &producer : producers) {
    producer.join();
  }

  for (auto &consumer : consumers) {
    consumer.join();
  }
}

int main() {
  std::cout << "Single Producer, Single Consumer Example:" << std::endl;
  SingleProducerSingleConsumerExample();

  std::cout << "\nMulti Producer, Multi Consumer Example:" << std::endl;
  MultiProducerMultiConsumerExample();

  return 0;
}
